﻿<script lang="ts" setup>
import { getEnumDisplayName } from '@/utils/enum'
import { formatToDateTime } from '@/utils/dateUtil'
import { ref, onMounted, onBeforeMount } from 'vue'
import { TreeSelectProps } from 'ant-design-vue'
import useCol from '@/hooks/system/useCol'
import * as api from '@/api/modules/role'
import { DefaultOptionType } from 'ant-design-vue/lib/select'
import { isEmpty } from '@/utils/is'

defineProps({
  isItem: { type: Boolean, default: false },
  itemData: Object,
  apiTreeData: Object,
  routeTreeData: Object,
})
const { getBindColumn } = useCol()

const apiTreeDataProxy = ref()
const routeTreeDataProxy = ref()

onMounted(async () => {
  if (apiTreeDataProxy.value === undefined) {
    apiTreeDataProxy.value = await getApiPermissionsTreeData();
  }

  if (routeTreeDataProxy.value === undefined) {
    routeTreeDataProxy.value = await getRoutePermissionsTreeData()
  }
})

const convertToApiDisplayName = (source: DefaultOptionType[], tag: string) => {
  if (source === undefined) {
    source = apiTreeDataProxy.value;
  }
  
  try {
    source.forEach(e => {
      (e.children as Omit<DefaultOptionType, 'children'>[]).forEach(ie => {
        if (ie.value == tag) {
          throw new Error(ie.title);
        }
      })
    })
  } catch (error) {
    return error.message;  
  } 

  return tag;  
}

const convertToRouteDisplayName = (source: DefaultOptionType[], tag: string) => {
  if (source === undefined) {
    source = routeTreeDataProxy.value;
  }

  try {
    source.forEach(e => {
      if (e.value == tag) {
        throw new Error(e.title);
      }
    })
  } catch (error) {
    return error.message;
  }
  
  return tag;
}

const getApiPermissionsTreeData = async (): Promise<TreeSelectProps['treeData']> => {
  let perms = await api.getApiPermissions();

  if (perms.data == undefined) {
    return;
  }

  let data = new Array<TreeSelectProps['treeData']>();

  perms.data.forEach(e => {
    let module = new Object();

    module.title = e.controllerDisplayName
    module.value = e.controller
    module.children = new Array<TreeSelectProps['treeData']>();

    for (let apiKey in e.apiInfo) {
      let api = new Object();
      api.title = e.apiInfo[apiKey];
      api.value = apiKey;

      module.children.push(api)
    }

    data.push(module)
  })

  return data as TreeSelectProps['treeData'];
}

const getRoutePermissionsTreeData = async (): Promise<TreeSelectProps['treeData']> => {
  let perms = await api.getRoutePermissions();

  if (perms.data == undefined) {
    return;
  }

  let data = new Array<TreeSelectProps['treeData']>();

  perms.data.forEach(e => {
    let module = new Object();

    module.title = e.controllerDisplayName
    module.value = e.name

    data.push(module)
  })

  return data as TreeSelectProps['treeData'];
}
</script>

<template>
  <div :class="['detail-wrapper', { isChild: isItem }]">
    <a-card class="basic-content">
      <a-descriptions v-bind="getBindColumn">
        <a-descriptions-item label="角色码">{{
        itemData?.roleCode
        }}</a-descriptions-item>
        <a-descriptions-item label="角色名称">{{
        itemData?.name
        }}</a-descriptions-item>
        <a-descriptions-item label="API权限">
          <div v-if="!isEmpty(itemData?.apiPermissions)">
            <a-tag color="green" v-for="tag in itemData?.apiPermissions" :key="tag">
              {{ convertToApiDisplayName(apiTreeData, tag) }}
            </a-tag>
          </div>
          <a-typography-text v-else type="secondary">
            <a-typography-text type="secondary">-</a-typography-text>
          </a-typography-text>          
        </a-descriptions-item>
        <a-descriptions-item label="视图权限">
          <div v-if="!isEmpty(itemData?.apiPermissions)">
            <a-tag color="orange" v-for="tag in itemData?.routePermissions" :key="tag">
              {{ convertToRouteDisplayName(routeTreeData, tag) }}
            </a-tag>
          </div>
          <a-typography-text v-else type="secondary">
            <a-typography-text type="secondary">-</a-typography-text>
          </a-typography-text>          
        </a-descriptions-item>
      </a-descriptions>
    </a-card>
  </div>
</template>

<style lang="less" scoped>
.detail-wrapper {
  :deep(.ant-card-head-title) {
    font-weight: 600;
  }

  .ant-card {
    margin: 24px;

    &.basic-content {
      margin: 0;
    }

    &:last-child {
      margin-bottom: 0;
    }
  }

  :deep(.ant-descriptions) {
    tbody>tr:last-child td {
      padding-bottom: 0;
    }
  }

  &.isChild {
    padding-bottom: 0;
    background-color: transparent;

    :deep(.ant-card) {
      margin: 0;
      margin-bottom: 24px;

      .ant-card-body {
        padding: 24px 24px 0;
      }
    }

    &:last-child {
      margin-bottom: 24px;
    }
  }
}
</style>

<style>
.ant-descriptions-item-container .ant-descriptions-item-label,
.ant-descriptions-item-container .ant-descriptions-item-content{
  display: table-cell;
}

.ant-tag {
  margin: 2px;
}
</style>